package com.example.kotlin_study.coroutine

import android.util.Log
import com.example.kotlin_study.coroutine.Coroutine.coroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

/**
 * author: wu-meng
 * date  : 2023/12/11
 * desc  : 协程相关
 */
object Coroutine {

    private const val TAG = "Coroutine"

    // withContext
    fun withContextCoroutine() {
        runBlocking {
            val result = withContext(Dispatchers.Default) {
                8 + 8
            }
            println(result)
        }
    }

    // async 创建协程 - 并行
    fun asyncCoroutine02() {
        runBlocking {
            val start = System.currentTimeMillis()

            val deferred1 = async {
                delay(1000)
                5 + 5
            }

            val deferred2 = async {
                delay(1000)
                6 + 6
            }

            println("result = ${deferred1.await() + deferred2.await()}")
            val end = System.currentTimeMillis()
            println("time = ${end - start}")
        }
    }

    // async创建协程-串行
    fun asyncCoroutine() {
        runBlocking {

            val start = System.currentTimeMillis()

            val result1 = async {
                delay(1000)
                5 + 5
            }.await()

            val result2 = async {
                delay(1000)
                6 + 4
            }.await()

            println("results = ${result1 + result2}")
            val end = System.currentTimeMillis()
            println("time = ${end - start}")
        }
    }

    fun coroutineCancel() {
        val job = Job()
        val scope = CoroutineScope(job)
        scope.launch {
            // 处理具体的逻辑
        }

        job.cancel()
    }

    fun runBlocking03() {
        runBlocking {
            coroutineScope {
                launch {
                    for (i in 0 .. 10) {
                        println(i)
                        delay(1000)
                    }
                }
            }
            println("coroutineScope finished")
        }
        println("runBlocking finished")
    }

    // 在suspend函数中，启动一个新的协程
    suspend fun printDot02() {
        coroutineScope {
            launch {
                println(".")
                delay(1000)
            }
        }
    }

    // 创建挂起函数
    suspend fun printDot() {
        println(".")
        delay(1000)
    }

    // 创建10万个协程
    fun runBlocking02() {
        val start = System.currentTimeMillis()
        runBlocking {
            repeat(100000) {
                launch {
                    println(".")
                }
            }
        }

        val end = System.currentTimeMillis()
        println("耗时: " + (end - start))
    }

    // 创建两个子协程
    fun runBlocking() {
        runBlocking {
            launch {
                println("launch1")
                delay(1000)
                println("launch1 finished")
            }

            launch {
                println("launch2")
                delay(1000)
                println("launch2 finished")
            }
        }
    }

    fun main05() {
        runBlocking {
            Log.d("main05","运行在协程域中")
            delay(5000)
            Log.d("main05","运行在协程域中finish")
        }

        Log.d("main05","主线程继续执行")
    }

    fun main04() {
        GlobalScope.launch {
            delay(5000)
            Log.d("main04","运行在协程域中")
        }

        Log.d("main04","主线程继续执行")
    }

    fun main01() {
        CoroutineScope(Dispatchers.IO).launch {
            println("协程开始")
            delay(1000)
            println("协程结束")
        }
    }

    fun main02() {
        GlobalScope.launch(Dispatchers.Main) {
            Log.d(TAG,Thread.currentThread().name)
        }
    }

    private val coroutineScope = CoroutineScope(Dispatchers.Main)

    fun main03() {
        coroutineScope.launch {
            delay(1000)
        }
    }

    fun start() {
        val runBlockingJob =  runBlocking {
            Log.d("runBlocking", "启动一个协程")
            41
        }
        Log.d("runBlockingJob", "$runBlockingJob")

        val launchJob = GlobalScope.launch {
            Log.d("launch", "启动一个协程")
        }
        Log.d("launchJob", "$launchJob")

        val asyncJob = GlobalScope.async {
            Log.d("async", "启动一个协程")
            "我是返回值"
        }
        Log.d("asyncJob","$asyncJob")
    }

}